//给你一个二叉搜索树的根节点 root ，返回 树中任意两不同节点值之间的最小差值 。 
//
// 差值是一个正数，其数值等于两值之差的绝对值。 
//
// 
//
// 示例 1： 
//
// 
//输入：root = [4,2,6,1,3]
//输出：1
// 
//
// 示例 2： 
//
// 
//输入：root = [1,0,48,null,null,12,49]
//输出：1
// 
//
// 
//
// 提示： 
//
// 
// 树中节点的数目范围是 [2, 104] 
// 0 <= Node.val <= 105 
// 
//
// 
//
// 注意：本题与 783 https://leetcode-cn.com/problems/minimum-distance-between-bst-node
//s/ 相同 
// Related Topics 树 深度优先搜索 广度优先搜索 二叉搜索树 二叉树 
// 👍 285 👎 0

package com.cute.leetcode.editor.cn;

import java.util.LinkedList;
import java.util.List;

public class MinimumAbsoluteDifferenceInBst {
    public static void main(String[] args) {
        Solution solution = new MinimumAbsoluteDifferenceInBst().new Solution();
    }
    public class TreeNode {
      int val;
      TreeNode left;
      TreeNode right;
      TreeNode() {}
      TreeNode(int val) { this.val = val; }
      TreeNode(int val, TreeNode left, TreeNode right) {
          this.val = val;
          this.left = left;
          this.right = right;
      }
  }
    //leetcode submit region begin(Prohibit modification and deletion)
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    /**
     * 思路很清晰：二叉搜索树的差值最小肯定发生在相邻节点之间，所以只需要遍历就行了，怎样一次遍历就能得到结果呢？
     * 我是使用了一个list存储的结果，然后遍历的list，时间和空间都有一些糟糕
     */

    TreeNode pre = null;
    Integer result = Integer.MAX_VALUE;
    List<Integer> list = new LinkedList<>();
    public int getMinimumDifference(TreeNode root) {
        infixOrder(root);
        Integer[] nums = list.toArray(new Integer[list.size()]);
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length -1; i++) {
            min = Math.min(min, nums[i+1]-nums[i]);
        }

        // 采用前驱节点的方法来实现
        traversal(root);
        return result;
    }
    public void infixOrder(TreeNode root){
        if (root == null) return;
        infixOrder(root.left);
        list.add(root.val);
        infixOrder(root.right);
    }

    /**
     * 优化方法：在递归内完成比较，需要一个变量保存前驱节点!!!
     * 我想过传值，返回值的方法都不行，前驱节点用的非常不错！！！
     * 如果前驱节点不为空就进行比较
     */
    public void traversal(TreeNode root){
        if(root==null) return;
        //左
        traversal(root.left);
        //中
        if(pre!=null){
            result = Math.min(result,root.val-pre.val);
        }
        pre = root;
        //右
        traversal(root.right);
    }


}
//leetcode submit region end(Prohibit modification and deletion)

}